#include <string.h>
#include "ebm_ts_parse.h"
#include "user_cfg.h"


#define EBM_CMD_PID  6692 /*指令PID */
const unsigned char tmp_id1[6]={0x95,0x11,};
#define EBM_CTLID  p_readcfg->ebm.logic_id



/*------------------*/
#define TS_FRAM_LEN 188


#if 1
#define TS_PARSE_DEBUG 	printf
#else
#define TS_PARSE_DEBUG(...) do{}while(0)
#endif

typedef struct {
	unsigned char   sync;
	unsigned short  pid;    /*mask :0x1FFF*/
	unsigned char   order:4;
    unsigned char   unused1:4;
    unsigned char   unused2;
	unsigned char   tableId; 	
	unsigned short  section_len;/*数据长度 包含CRC， mask :0x0FFF*/
	unsigned char   check_byte;  /*h+l= 24*/
	unsigned char   cmdCnt; 		/*指令次数*/
	unsigned char   cmdLv:3;		/*指令等级*/
	unsigned char   cmdBit:3;	    /*指令位移*/
    unsigned char   cmdType:2;	/*指令类型*/
    unsigned char   log_addr[6];
	unsigned char   reserved:2;
	unsigned char   vol_ch:3;
	unsigned char   em_flag:1;
	unsigned char   sw_sta:2;;
	unsigned short  pgId;
}__attribute__((packed))tsHead;

typedef struct {
	unsigned char   cmdLv:3;		/*指令等级*/
	unsigned char   cmdBit:3;	    /*指令位移*/
    unsigned char   cmdType:2;	/*指令类型*/
    unsigned char   log_addr[6];
	unsigned char   reserved:2;
	unsigned char   vol_ch:3;
	unsigned char   em_flag:1;
	unsigned char   sw_sta:2;;
	unsigned short  pgId;
}__attribute__((packed))pgHead;


const char *emFlagStr[]={"普通", "应急"};
#define playWcntMax 16  /**/
#define cmdWcntMax 60

PgInfo current_pg;


unsigned char nstar_pack_loadbytes(unsigned char *buf, unsigned char buflen, unsigned char type)
{
#define LOAD_BYTES_LEN 	17
    const unsigned char load_bytes[LOAD_BYTES_LEN] = {0x02, 0x00, 0x0e, 0x51, 0x01 ,0x08, \
        0x01, 0x01, 0x09, 0x15, 0x08, 0x05, 0x50, 0x10, 0x01, 0x1a, 0x23};

	if(buflen < LOAD_BYTES_LEN)
        return 0;
	memcpy(buf, load_bytes, LOAD_BYTES_LEN);
    memcpy(buf+3, EBM_CTLID, 6);
    buf[15] = EBM_CMD_PID >> 8;
    buf[16] = EBM_CMD_PID & 0xff;
    return LOAD_BYTES_LEN;
}

static unsigned char _parse_tsType(unsigned char *buf) {
    unsigned char ret = 0, cmdType, cnt;
    unsigned short cmdPid = (buf[1] << 0x8 | buf[2])&0x1fff;
    if(EBM_CMD_PID != cmdPid)
        return 0;
    cmdType = buf[10] >> 6;
    cnt = buf[9];
    switch(cmdType) {
    case 0:
        if(cnt == 0 && buf[10] == 0) {

        }else {
            ret = 1;
        }
        break;
    case 1:
    case 2:
    case 3:
        break;
    }
    return ret;
}



void make_pgInfo(PgInfo* pg, char* buf, unsigned int len) {
    if(len > 0) {
        unsigned char *p = pg->logicAddr;
        unsigned char em = pg->emFlag? 1 : 0;
        snprintf(buf, len, "%d，%02X%02X%02X%02X%02X%02X，%s", \
          pg->pgId, p[0],p[1],p[2],p[3],p[4],p[5], emFlagStr[em]);
    }
}

static int lenthLogicId(unsigned char *id) {
	int i;
    for(i = 0; i < 6; i++) {
        if(id[i] == 0xff) {
            break;
        }
    }
	return i;
}


static unsigned char _search_pg(unsigned char *data, PgInfo* pg) {
    enum{
        none = 0,
		update = 1,
		hold = 2
    };
    unsigned char ret = none;
    pgHead *pts = (pgHead*)data;
    pts->pgId = Swap16(pts->pgId);
    //myarray(data, 32);
    switch (pts->sw_sta) {
    case pgCmdStop:
        if(pg->swSta != pgCmdStop && pg->pgId == pts->pgId) {
            PgCmd_Stop(pg);
        }
        break;
    default:
        
        if (pts->em_flag < pg->emFlag || pts->cmdLv < pg->cmdLv) {
            TS_PARSE_DEBUG( "not a vaild pg , lv too low\n");
			break;
		}
    	if (pg->swSta == pgCmdStop) {
			TS_PARSE_DEBUG( "new pg 1st one\n");
			ret = update;
		}
        
        if (pts->em_flag > pg->emFlag) {
			TS_PARSE_DEBUG("new pg higher emFlag\n");
			ret = update;
		}else if (pts->cmdLv > pg->cmdLv) {
			TS_PARSE_DEBUG( "new pg higher cmdLv\n");
			ret = update;
		}else if (lenthLogicId(pts->log_addr) < lenthLogicId(pg->logicAddr) ) {
			TS_PARSE_DEBUG("new pg shorter logicID\n");
			ret = update ;
		}else if (pts->pgId == pg->pgId) {
			//TS_PARSE_DEBUG("pg hold %d\n", pts->pgId);
			ret = hold;
		}

        if (ret > none){
			pg->playwcnt = playWcntMax;
			if (ret == update) {
                char buf[40];
				pg->cmdLv 	= pts->cmdLv;
				pg->swSta	= pts->sw_sta;
				pg->emFlag	= pts->em_flag;
				pg->pgId	= pts->pgId;
				memcpy(pg->logicAddr, pts->log_addr, 6);
				make_pgInfo(pg, buf, 40);
				TS_PARSE_DEBUG("PG更新: %s\n", buf);		
                ebm_play_cmd_open();
			}else if(ret == hold) {
                ebm_play_cmd_keepon();
            }
		}

        break;
    }

}


unsigned char nstar_parse_msg(unsigned char *buf, unsigned short buflen)
{

    
    unsigned char *data = buf;
    while(buflen > sizeof(tsHead)) {
        if(data[0] == 0x47 && buflen >= TS_FRAM_LEN) {
            unsigned short datalen = buflen;
            buflen-= TS_FRAM_LEN;
            if(0 == _parse_tsType(data)) {
                TS_PARSE_DEBUG("nstar parse msg tsType, left %d\n", buflen);
                continue;
            }else {
                int cnt = data[9];
                data+=10;
                datalen-=10;
                for(; cnt > 0 && datalen > 10; cnt--) {
                    _search_pg(data, &current_pg);
                    datalen-= sizeof(pgHead);
                    data+= sizeof(pgHead);
                } 
            }
        }else {
            TS_PARSE_DEBUG("nstar parse msg sync bytes, buflen %d\n", buflen);
            buflen--;
            data++;
        }
    }
}










